﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace FindModel
{
    public partial class MainFrm : Form
    {
        public MainFrm()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 选择excel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pdSelect_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog2 = new OpenFileDialog();
            //openFileDialog2.InitialDirectory = System.IO.Directory.GetCurrentDirectory();
            openFileDialog2.Filter = "excel (2007)(*.xlsx)|*.xlsx|excel (97-2003)(*.xls)|*.xls";
            if (openFileDialog2.ShowDialog() == DialogResult.OK)
            {
                pdExcel.Text = openFileDialog2.FileName;
            }
        }

        /// <summary>
        /// 选择文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectFolder_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                txtFolder.Text = folderBrowserDialog.SelectedPath;
            }
        }

        /// <summary>
        /// 选择PD文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectPDFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog2 = new OpenFileDialog();
            //openFileDialog2.InitialDirectory = System.IO.Directory.GetCurrentDirectory();
            openFileDialog2.Filter = "PD文件(*.pdm)|*.pdm";
            if (openFileDialog2.ShowDialog() == DialogResult.OK)
            {
                txtPDFile.Text = openFileDialog2.FileName;
            }
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAnalysis_Click(object sender, EventArgs e)
        {
            dgvModel.DataSource = null;
            dgvPD.DataSource = null;
            if (string.IsNullOrWhiteSpace(txtFolder.Text))
            {
                MessageBox.Show("文件夹未选择");
            }

            if (string.IsNullOrWhiteSpace(txtInterface.Text))
            {
                MessageBox.Show("继承接口未设置");
            }

            if (string.IsNullOrWhiteSpace(pdExcel.Text) || string.IsNullOrWhiteSpace(txtPDFile.Text))
            {
                MessageBox.Show("PDExcel不存在或PD文件不存在");
            }
            SetModelDT();
            SetPDDT();

            Analysis();
            tab1.SelectedTab = tabResult;
            this.WindowState = FormWindowState.Maximized;
            //MessageBox.Show("解析完成");
        }

        DataTable modelDT = new DataTable();
        DataTable pdDT = new DataTable();

        /// <summary>
        /// 设置实体表
        /// </summary>
        private void SetModelDT()
        {
            var dir = new DirectoryInfo(txtFolder.Text);//($@"F:\医院物流管理系统\05 医院物流管理系统(改进版)\02 代码类\01 源代码\08 SPD耗材物流管理系统\QuickShare.MaterialSpd.API\QuickShare.MaterialSpd.Web\bin");
            var files = dir.GetFiles("*.dll");
            List<Assembly> assemblies = new List<Assembly>();
            foreach (var file in files)
            {
                var ass = Assembly.Load(AssemblyName.GetAssemblyName(file.FullName));
                assemblies.Add(ass);
            }

            List<Type> types = new List<Type>();
            foreach (var item in assemblies)
            {
                try
                {
                    types.AddRange(item.ExportedTypes.Where(p => p.IsClass && p.GetInterface(txtInterface.Text) != null).ToList());
                }
                catch
                {
                    continue;
                }
            }
            modelDT = new DataTable();
            foreach (var item in types)
            {
                modelDT.Columns.Add(item.Name);
            }
            var max = types.Max(p => p.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Static
                    | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Count());
            for (int i = 0; i < max; i++)
            {
                modelDT.Rows.Add(modelDT.NewRow());
            }
            for (int i = 0; i < types.Count; i++)
            {
                int rows = 0;
                foreach (var item in types[i].GetFields(BindingFlags.DeclaredOnly | BindingFlags.Static
                    | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(p => p.FieldType.GetInterface("IEnumerable") == null || p.FieldType == typeof(string)).Select(p => p.Name).ToList())
                {
                    modelDT.Rows[rows][i] = GetFieldName(item);
                    rows++;
                }
            }

            //dgvModel.DataSource = modelDT;
        }

        /// <summary>
        /// 设置PD表
        /// </summary>
        private void SetPDDT()
        {
            if (!string.IsNullOrWhiteSpace(txtPDFile.Text))
            {
                PdmFileReader pdmFileReader = new PdmFileReader();
                var Tables = pdmFileReader.ReadFromFile(txtPDFile.Text).Tables;
                pdDT = new DataTable();
                foreach (var item in Tables)
                {
                    pdDT.Columns.Add(item.Code);
                }
                var max = Tables.Max(p => p.Columns.Count);
                for (int i = 0; i < max + 1; i++)
                {
                    pdDT.Rows.Add(pdDT.NewRow());
                }
                foreach (var item in Tables)
                {
                    pdDT.Rows[0][item.Code] = item.Name;
                    for (int i = 1; i < item.Columns.Count + 1; i++)
                    {
                        pdDT.Rows[i][item.Code] = item.Columns[i - 1].Code;
                    }
                }
            }
            else
            {
                pdDT = new DataTable();
                ExcelHelper eh1 = new ExcelHelper(pdExcel.Text);
                pdDT = eh1.ExportExcelToDataTable();
            }
            //dgvPD.DataSource = pdDT;
        }

        //变红使用
        Dictionary<string, List<string>> redPd = new Dictionary<string, List<string>>();
        Dictionary<string, List<string>> redmodel = new Dictionary<string, List<string>>();

        /// <summary>
        /// 解析
        /// </summary>
        private void Analysis()
        {
            Dictionary<string, List<string>> pdduo = new Dictionary<string, List<string>>();
            Dictionary<string, List<string>> modelduo = new Dictionary<string, List<string>>();
            var modelDic = DT2DIC(modelDT);
            var pdDic = DT2DIC(pdDT);

            var modelKey = modelDic.Select(p => p.Key);
            var pdKey = pdDic.Select(p => p.Key);
            foreach (var item in modelKey.Where(p => !pdKey.Contains(p)))
            {
                modelduo.Add(item, modelDic[item]);
                //modelDic.Remove(item);
            }
            foreach (var item in pdKey.Where(p => !modelKey.Contains(p)))
            {
                pdduo.Add(item, pdDic[item]);
                //pdDic.Remove(item);
            }
            foreach (var item in modelduo)
            {
                modelDic.Remove(item.Key);
            }
            foreach (var item in pdduo)
            {
                pdDic.Remove(item.Key);
            }

            modelDic = modelDic.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
            pdDic = pdDic.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
            ////最终结果使用
            //var pd = new Dictionary<string, List<string>>();
            //var model = new Dictionary<string, List<string>>();
            //变红使用
            //var redPd = new Dictionary<string, List<string>>();
            //var redmodel = new Dictionary<string, List<string>>();
            redPd.Clear();
            redmodel.Clear();
            //检查多出的值
            foreach (var item in pdDic)
            {
                var pdValue = item.Value;
                var modelValue = modelDic[item.Key];

                redPd.Add(item.Key, pdValue.Where(p => !modelValue.Contains(p)).ToList());
                redmodel.Add(item.Key, modelValue.Where(p => !pdValue.Contains(p)).ToList());
            }
            //多余的表加回去
            foreach (var item in modelduo)
            {
                modelDic.Add(item.Key, item.Value);
            }
            foreach (var item in pdduo)
            {
                pdDic.Add(item.Key, item.Value);
            }

            modelDT = DIC2DT(modelDic);
            pdDT = DIC2DT(pdDic);

            dgvModel.DataSource = modelDT;
            dgvPD.DataSource = pdDT;
            //变色
            dgvPD.EnableHeadersVisualStyles = false;
            dgvModel.EnableHeadersVisualStyles = false;
            for (int i = 0; i < dgvModel.Columns.Count; i++)
            {
                if (modelduo.Keys.ToList().Contains(dgvModel.Columns[i].Name))
                    dgvModel.Columns[i].HeaderCell.Style.BackColor = Color.Green;

                //if (redmodel.Keys.Contains(dgvModel.Columns[i].Name))
                //{
                //    var list = redmodel[dgvModel.Columns[i].Name];
                //    for (int j = 0; j < dgvModel.Rows.Count; j++)
                //    {
                //        if (list.Contains(dgvModel.Rows[j].Cells[i].Value))
                //        {
                //            //dgvModel.Rows[j].Cells[i].Style.ForeColor = Color.Red;
                //            dgvModel[i, j].Style.BackColor = Color.Red;
                //        }


                //    }
                //}
            }

            for (int i = 0; i < dgvPD.Columns.Count; i++)
            {
                if (pdduo.Keys.ToList().Contains(dgvPD.Columns[i].Name))
                    dgvPD.Columns[i].HeaderCell.Style.BackColor = Color.Green;

                //if (redPd.Keys.Contains(dgvPD.Columns[i].Name))
                //{
                //    var list = redPd[dgvPD.Columns[i].Name];
                //    for (int j = 0; j < dgvPD.Rows.Count; j++)
                //    {
                //        if (list.Contains(dgvPD.Rows[j].Cells[i].Value))
                //        {
                //            dgvPD.Rows[j].Cells[i].Style.ForeColor = Color.Red;
                //        }


                //    }
                //}
            }
            //dgvModel.Refresh();
            //dgvPD.Refresh();

        }

        private Dictionary<string, List<string>> DT2DIC(DataTable dt)
        {
            Dictionary<string, List<string>> dic = new Dictionary<string, List<string>>();
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                List<string> list = new List<string>();
                for (int j = 0; j < dt.Rows.Count; j++)
                {
                    if (string.IsNullOrWhiteSpace(dt.Rows[j][i].ToString()))
                    {
                        break;
                    }
                    else
                    {
                        list.Add(dt.Rows[j][i].ToString());
                    }
                }
                dic.Add(dt.Columns[i].ColumnName, list);
            }
            return dic;
        }


        private DataTable DIC2DT(Dictionary<string, List<string>> dic)
        {
            DataTable dt = new DataTable();
            foreach (var item in dic.Keys)
            {
                dt.Columns.Add(item);
            }
            var max = dic.Values.Max(p => p.Count);
            for (int i = 0; i < max; i++)
            {
                dt.Rows.Add(dt.NewRow());
            }

            foreach (var item in dic)
            {
                for (int i = 0; i < item.Value.Count; i++)
                {
                    dt.Rows[i][item.Key] = item.Value[i];
                }
            }

            return dt;
        }

        /// <summary>
        /// 获取字段的名称
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        private string GetFieldName(string field)
        {
            Regex reg = new Regex(@"<([\w\W]*)>");
            Match match = reg.Match(field);
            if (match.Success)
            {
                return match.Groups[1].Value;
            }
            else
            {
                return field;
            }
        }


        /// <summary>
        /// 变色事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvPD_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (redPd.Count() > 0)
            {
                if (redPd.ContainsKey(dgvPD.Columns[e.ColumnIndex].Name))
                {
                    var list = redPd[dgvPD.Columns[e.ColumnIndex].Name];
                    if (list.Any() && list.Contains(e.Value))
                    {
                        e.CellStyle.ForeColor = Color.Red;
                        dgvPD.Columns[e.ColumnIndex].HeaderCell.Style.BackColor = Color.Red;
                    }
                }

            }
        }

        /// <summary>
        /// 变色事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvModel_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (redmodel.Count() > 0)
            {
                if (redmodel.ContainsKey(dgvModel.Columns[e.ColumnIndex].Name))
                {
                    var list = redmodel[dgvModel.Columns[e.ColumnIndex].Name];
                    if (list.Any() && list.Contains(e.Value))
                    {
                        e.CellStyle.ForeColor = Color.Red;
                        dgvModel.Columns[e.ColumnIndex].HeaderCell.Style.BackColor = Color.Red;
                    }
                }


            }
        }

        private void btnWord_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtPDFile.Text))
            {
                MessageBox.Show("PD文件不存在");
            }
            PdmFileReader pdmFileReader = new PdmFileReader();
            var Tables = pdmFileReader.ReadFromFile(txtPDFile.Text).Tables.OrderBy(p => p.Code).ToList();
            WordHelper wordHelper = new WordHelper();
            Task.Run(() =>
            {
                wordHelper.CreateWord(Tables);
            });
        }
    }
}
